import { AES, enc, mode, pad } from "crypto-js";
import * as fflate from "fflate";
import { weBtoa, weAtob } from "./weAppJwt";

export class EncryptionToDecrypt {
  static keyStr = "8e61c760fc65b76a";
  static iv = "55f305bc47281b07";

  /**
   * 加密
   * @param {string} word 加密内容
   */

  static encryptionCryptoJS(word: string) {
    const key = enc.Utf8.parse(this.keyStr);
    const sacs = enc.Utf8.parse(word);
    const encrypted = AES.encrypt(sacs, key, {
      iv: enc.Utf8.parse(this.iv),
      mode: mode.CBC,
      padding: pad.Pkcs7,
    });
    const hexStr = encrypted.ciphertext.toString().toUpperCase();
    return hexStr.toString();
  }

  /**
   * 解密
   * @param {string} word  解密内容
   */

  static decryptionCryptoJS(word: string) {
    if (typeof word === "object") {
      return word;
    }
    const key = enc.Utf8.parse(this.keyStr);
    const encryptedHexStr = enc.Hex.parse(word);
    const sacs = enc.Base64.stringify(encryptedHexStr);
    const decrypt = AES.decrypt(sacs, key, {
      iv: enc.Utf8.parse(this.iv),
      mode: mode.CBC,
      padding: pad.Pkcs7,
    });

    const data = this.unGzip(enc.Utf8.stringify(decrypt).toString()) as string;

    return JSON.parse(data);
  }

  /**
   * 解压 Gzip 数据
   * @param {string} b64Data 解压
   */
  static unGzip(b64Data: string) {
    if (!b64Data) {
      return "";
    }
    let decompress: Uint8Array;
    // #ifdef MP-WEIXIN
    decompress = fflate.decompressSync(fflate.strToU8(weAtob(b64Data), true));
    return fflate.strFromU8(decompress);
    // #endif

    // #ifdef H5
    decompress = fflate.decompressSync(fflate.strToU8(atob(b64Data), true));
    return fflate.strFromU8(decompress);
    // #endif
  }

  /**
   * 解决中文乱码
   * @param {*} arr
   */
  static byteToString(arr: any) {
    if (typeof arr === "string") {
      return arr;
    }
    let str = "";
    let _arr = arr;
    for (let i = 0; i < _arr.length; i++) {
      let one = _arr[i].toString(2);
      let v = one.match(/^1+?(?=0)/);
      if (v && one.length == 8) {
        let bytesLength = v[0].length;
        let store = _arr[i].toString(2).slice(7 - bytesLength);
        for (let st = 1; st < bytesLength; st++) {
          store += _arr[st + i].toString(2).slice(2);
        }
        str += String.fromCharCode(parseInt(store, 2));
        i += bytesLength - 1;
      } else {
        str += String.fromCharCode(_arr[i]);
      }
    }
    return str;
  }
}
